/* * Copyright (c) 2009-2012 Sonatype, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * and Apache License v2.0 which accompanies this distribution. * The Eclipse Public License is available at * http://www.eclipse.org/legal/epl-v10.html * The Apache License v2.0 is available at * http://www.apache.org/licenses/LICENSE-2.0.html * You may elect to redistribute this code under either of these licenses. */ package org.sonatype.sisu.maven.bridge.support.dependency.internal; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import javax.annotation.Nullable; import javax.inject.Provider; import org.sonatype.sisu.maven.bridge.MavenDependencyTreeResolver; import org.sonatype.sisu.maven.bridge.MavenModelResolver; import org.sonatype.sisu.maven.bridge.internal.ComponentSupport; import org.sonatype.sisu.maven.bridge.support.CollectRequestBuilder; import org.apache.maven.model.Model; import org.apache.maven.model.Repository; import org.apache.maven.model.building.ModelBuildingException; import org.apache.maven.model.building.ModelBuildingRequest; import org.eclipse.aether.RepositorySystem; import org.eclipse.aether.RepositorySystemSession; import org.eclipse.aether.artifact.Artifact; import org.eclipse.aether.artifact.ArtifactProperties; import org.eclipse.aether.artifact.ArtifactType; import org.eclipse.aether.artifact.ArtifactTypeRegistry; import org.eclipse.aether.artifact.DefaultArtifact; import org.eclipse.aether.artifact.DefaultArtifactType; import org.eclipse.aether.collection.CollectRequest; import org.eclipse.aether.collection.CollectResult; import org.eclipse.aether.collection.DependencyCollectionException; import org.eclipse.aether.graph.Dependency; import org.eclipse.aether.graph.DependencyNode; import org.eclipse.aether.graph.Exclusion; import org.eclipse.aether.impl.RemoteRepositoryManager; import org.eclipse.aether.repository.RemoteRepository; import org.eclipse.aether.spi.locator.ServiceLocator; import static org.sonatype.sisu.maven.bridge.support.RemoteRepositoryBuilder.remoteRepository; public abstract class MavenDependencyTreeResolverSupport extends ComponentSupport implements MavenDependencyTreeResolver { protected static final Provider<RepositorySystemSession> NO_SESSION_PROVIDER = null; private MavenModelResolver mavenModelResolver; private Provider<RepositorySystemSession> sessionProvider; private RepositorySystem repositorySystem; private RemoteRepositoryManager remoteRepositoryManager; protected MavenDependencyTreeResolverSupport(final ServiceLocator serviceLocator, final @Nullable MavenModelResolver mavenModelResolver) { this(serviceLocator, mavenModelResolver, NO_SESSION_PROVIDER); } protected MavenDependencyTreeResolverSupport(final ServiceLocator serviceLocator, final @Nullable MavenModelResolver mavenModelResolver, final @Nullable Provider<RepositorySystemSession> sessionProvider) { repositorySystem = serviceLocator.getService(RepositorySystem.class); remoteRepositoryManager = serviceLocator.getService(RemoteRepositoryManager.class); this.sessionProvider = sessionProvider; this.mavenModelResolver = mavenModelResolver; } @Override public DependencyNode resolveDependencyTree(final CollectRequestBuilder requestBuilder, final RepositorySystemSession session, final RemoteRepository... repositories) throws DependencyCollectionException { final CollectRequest request = requestBuilder.getCollectRequest(); final ModelBuildingRequest modelBuildingRequest = requestBuilder.getModelBuildingRequest(); Model model = requestBuilder.getModel(); if (model == null && modelBuildingRequest != null) { model = resolveModel(request, session, modelBuildingRequest); } if (model != null) { injectCollectionRequest(request, session, model); } return repositorySystem.collectDependencies(session, request).getRoot(); } @Override public DependencyNode resolveDependencyTree(final CollectRequestBuilder request, final RemoteRepository... repositories) throws DependencyCollectionException { return resolveDependencyTree(request, assertNotNull(sessionProvider, "Repository system session provider not specified").get()); } protected RemoteRepositoryManager getRemoteRepositoryManager() { return remoteRepositoryManager; } protected RepositorySystem getRepositorySystem() { return repositorySystem; } private void injectCollectionRequest(final CollectRequest request, final RepositorySystemSession session, final Model model) { for (final Repository repository : model.getRepositories()) { request.addRepository(remoteRepository(repository)); } final ArtifactTypeRegistry stereotypes = session.getArtifactTypeRegistry(); for (final org.apache.maven.model.Dependency dep : model.getDependencies()) { request.addDependency(toDependency(dep, stereotypes)); } if (model.getDependencyManagement() != null) { for (final org.apache.maven.model.Dependency dep : model.getDependencyManagement().getDependencies()) { request.addManagedDependency(toDependency(dep, stereotypes)); } } } private Model resolveModel(final CollectRequest request, final RepositorySystemSession session, final ModelBuildingRequest modelBuildingRequest) throws DependencyCollectionException { final Model model; try { model = assertNotNull(mavenModelResolver, "Maven model resolver is not set").resolveModel(modelBuildingRequest, session); } catch (final ModelBuildingException e) { final CollectResult collectResult = new CollectResult(request); collectResult.addException(e); throw new DependencyCollectionException(collectResult) { @Override public String getMessage() { return e.getMessage(); } }; } return model; } private Dependency toDependency(final org.apache.maven.model.Dependency dependency, final ArtifactTypeRegistry stereotypes) { ArtifactType stereotype = stereotypes.get(dependency.getType()); if (stereotype == null) { stereotype = new DefaultArtifactType(dependency.getType()); } final boolean system = dependency.getSystemPath() != null && dependency.getSystemPath().length() > 0; Map<String, String> props = null; if (system) { props = Collections.singletonMap(ArtifactProperties.LOCAL_PATH, dependency.getSystemPath()); } final Artifact artifact = new DefaultArtifact(dependency.getGroupId(), dependency.getArtifactId(), dependency.getClassifier(), null, dependency.getVersion(), props, stereotype); final List<Exclusion> exclusions = new ArrayList<Exclusion>(dependency.getExclusions().size()); for (final org.apache.maven.model.Exclusion exclusion : dependency.getExclusions()) { exclusions.add(toExclusion(exclusion)); } return new Dependency(artifact, dependency.getScope(), dependency.isOptional(), exclusions); } private Exclusion toExclusion(final org.apache.maven.model.Exclusion exclusion) { return new Exclusion(exclusion.getGroupId(), exclusion.getArtifactId(), "*", "*"); } }